﻿namespace LaoLuo
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// A servant will be on duty every some time, and can do some work of any type when request is get
    /// </summary>
    public class Servant : IDisposable
    {
        /// <summary>
        /// timer for duty
        /// </summary>
        private TimerWithAlarm _timer;

        /// <summary>
        /// action to do on duty
        /// </summary>
        private Action _duty;

        /// <summary>
        /// init a <see cref="Servant"/>
        /// </summary>
        /// <param name="duty">action to do on duty</param>
        /// <param name="interval">duty interval</param>
        public Servant(Action duty, TimeSpan interval)
            : this(duty, interval.TotalMilliseconds)
        {
        }

        /// <summary>
        /// init a <see cref="Servant"/>
        /// </summary>
        /// <param name="duty">action to do on duty</param>
        /// <param name="interval">duty interval</param>
        public Servant(Action duty, double interval)
        {
            this._duty = duty;
            this._timer = new TimerWithAlarm(duty, interval);
        }

        /// <summary>
        /// give some work to the servant
        /// </summary>
        /// <typeparam name="T">type of work</typeparam>
        /// <param name="action">action to handle a work</param>
        /// <param name="work">works to do</param>
        public void Do<T>(Action<T> action, IEnumerable<Work<T>> work)
        {
            Worker.Do(action, work);
        }

        /// <summary>
        /// give some work to the servant
        /// </summary>
        /// <typeparam name="T">type of work</typeparam>
        /// <param name="action">action to handle a work</param>
        /// <param name="work">works to do</param>
        public void Do<T>(Action<T> action, params Work<T>[] work)
        {
            Do(action, work.AsEnumerable());
        }

        public void Dispose()
        {
            _timer.Stop();
            _timer.Dispose();
            _duty = null;
        }
    }
}
